#include "widget.h"
#include "ui_widget.h"
#include <vector>
#include <list>
#include <QString>
#include <map>
#include <QFileDialog>
#include <QFile>
#include <QTimer>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include<QAction>
#include <QMenu>
#include <queue>

struct WidgetPrivate
{
    //播放者
    QMediaPlayer *player;
    //判断是否有歌曲播放
    bool isplay=false;
    //样式表
    int count=1;
    //用于进行网络请求的 QNetworkAccessManager 对象
    QNetworkAccessManager *http_acc;
    //用于定时更新播放进度的 QTimer 对象。
    QTimer timer ;
    //保存用户在搜索歌单中选择的行数
    int songrow=0;
    //保存用户在我的歌单中选择的行数
    int mysongrow=0;
    //循环和单曲循环的标志位
    bool songswitch=true;
    //保存此时播放音乐的url
    QString url;
    //用于连接和操作 SQLite 数据库的 QSqlDatabase 对象
    QSqlDatabase db;
    //搜索歌单列表
    std::map<int,QString> searchmusictime;
    std::map<int,QString> searchmusicname;
    std::map<int,QString> searchmusicurl;
    //我的歌单列表
    std::map<int,QString> Musictime;
    std::map<int,QString> Musicname;
    std::map<int,QString> Musicurl;
    QPixmap m_background;
};

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget),p(new WidgetPrivate)
{
    ui->setupUi(this);
    //控件位置大小的设置
    this->setFixedSize(840,700);
    ui->label->setGeometry(0,0,840,700);
    ui->seach_for_song->setGeometry(105,30,530,30);
    ui->search_for->setGeometry(655,30,60,30);
    ui->songlabel->setGeometry(180,70,70,30);
    ui->mysonglabel->setGeometry(555,70,70,30);
    ui->song->setGeometry(90,110,270,370);
    ui->mysong->setGeometry(460,110,270,370);
    ui->playinglabel->setGeometry(385,470,70,30);
    ui->playing->setGeometry(325,505,190,30);
    ui->previoussong->setGeometry(210,550,60,60);
    ui->cease_start->setGeometry(400,550,60,60);
    ui->nextsong->setGeometry(570,550,60,60);
    ui->localsong->setGeometry(10,650,40,40);
    ui->schedule->setGeometry(100,630,640,10);
    ui->musicstart->setGeometry(55,623,40,20);
    ui->musicend->setGeometry(750,623,40,20);
    ui->personalization->setGeometry(690,650,40,40);
    ui->songswitch->setGeometry(740,650,40,40);
    ui->sound->setGeometry(805,550,10,100);
    ui->volume->setGeometry(790,650,40,40);
    setWindowTitle("音乐播放器");
    ui->seach_for_song->setPlaceholderText("音乐/歌手");
    //贴图
    setWindowIcon(QIcon(":/picture/music.png"));
    QAction *actionpassword=new QAction;
    actionpassword->setIcon(QIcon(":/picture/search.png"));
    ui->seach_for_song->addAction(actionpassword,QLineEdit::LeadingPosition);
    ui->personalization->setIcon(QIcon(":/picture/personalization.png"));
    ui->nextsong->setIcon(QIcon(":/picture/next.png"));
    ui->previoussong->setIcon(QIcon(":/picture/previous.png"));
    ui->localsong->setIcon(QIcon(":/picture/local.png"));
    ui->cease_start->setIcon(QIcon(":/picture/start.png"));
    ui->songswitch->setIcon(QIcon(":/picture/cyclic.png"));
    ui->volume->setIcon(QIcon(":/picture/sound.png"));

    Initqss(":/qss/1.qss");
    p->player=new QMediaPlayer;
    p->http_acc=new QNetworkAccessManager;
    //数据库数据的导入
    Sqlite();
    //音量按钮设置有选中和非选中状态
    ui->volume->setCheckable(true);
    //音量滑轨的隐藏
    ui->sound->setVisible(false);
    ui->sound->setRange(0,100);    //设置滑轨范围
    ui->sound->setValue(20);   //设置初始值
    connect(ui->sound,&QSlider::sliderMoved,this,&Widget::soundmove);
    connect(p->http_acc,SIGNAL(finished(QNetworkReply*)),this,SLOT(recv_ack(QNetworkReply*)));
    //右击搜索列表加入歌单
    ui->song->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->song, &QListWidget::customContextMenuRequested, this, &Widget::showContextMenu);
    //右击歌单列表删除歌曲
    ui->mysong->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->mysong, &QListWidget::customContextMenuRequested, this, &Widget::showMysongMenu);
    //单击搜索歌单列表，在线听歌
    connect(ui->song, &QListWidget::itemClicked, [=](QListWidgetItem *item) {
        p->songrow = ui->song->currentRow();
        onlinePlay();
    });
    //单击我的歌单列表，播放音乐
    connect(ui->mysong, &QListWidget::itemClicked, [=](QListWidgetItem *item)
    {
        p->isplay=true;
        p->mysongrow=ui->mysong->currentRow();
        ui->playing->setText(item->text());
        p->player->setMedia(QUrl(p->Musicurl[p->mysongrow]));
        qDebug()<<p->Musicurl[p->mysongrow]<<endl;
        p->url=p->Musicurl[p->mysongrow];
        p->player->play();
        ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
    });
    //歌曲时长
    connect(p->player,&QMediaPlayer::durationChanged,[this]()
    {
        QString TotalTime = QString("%1:%2").arg(p->player->duration()/1000/60).arg(p->player->duration()/1000%60);
        qDebug()<<TotalTime<<endl;
        ui->musicend->setText(TotalTime);
        ui->schedule->setRange(0,p->player->duration());
    });
    //歌曲当前时长
    connect(p->player,&QMediaPlayer::positionChanged,[this]()
    {
        QString CurrentTime = QString("%1:%2").arg(p->player->position()/1000/60).arg(p->player->position()/1000%60);
        ui->musicstart->setText(CurrentTime);
        ui->schedule->setValue(p->player->position());
    });
    //进度滑轨的移动
    connect(ui->schedule,&QSlider::sliderMoved,[this]()
    {
        QString CurrentTime = QString("%1:%2").arg(p->player->position()/1000/60).arg(p->player->position()/1000%60);
        ui->musicstart->setText(CurrentTime);
        p->player->setPosition(ui->schedule->value());
    });
    //音乐播放结束，单曲循环或循环播放的控制
    connect(p->player, &QMediaPlayer::mediaStatusChanged, this, &Widget::onMediaStatusChanged);
}

Widget::~Widget()
{
    //我的歌单数据存入数据库
    QSqlQuery query;
    query.exec("DELETE FROM musicdata");
    if (query.lastError().isValid()) {
        qDebug() << "Failed to delete records:" << query.lastError().text();
    }
    qDebug()<<p->Musicurl.size()<<endl;
    for (int i=0;i<p->Musicurl.size();i++)
    {
        qDebug()<<p->Musictime[i]<<endl;
        qDebug()<<p->Musicname[i]<<endl;
        qDebug()<<p->Musicurl[i]<<endl;
        QSqlQuery query;
        query.prepare("INSERT INTO musicdata (musictime, musicname, musicurl) VALUES (:musictime, :musicname, :musicurl)");
        query.bindValue(":musictime", p->Musictime[i]);
        query.bindValue(":musicname", p->Musicname[i]);
        query.bindValue(":musicurl", p->Musicurl[i]);
        if (!query.exec())
        {
            qDebug() << "Failed to insert record:" << query.lastError().text();
        }
    }
    p->db.close();
    delete p->player;
    delete p->http_acc;
    delete p;
    delete ui;
}
void Widget::Initqss(const QString &qsspath)
{
    QFile file(qsspath);
    if(file.open(QIODevice::ReadOnly)==false)
    {
        qDebug()<<"open qss file fail\n";
        return;
    }
    QString Qsscontent=file.readAll();
    qApp->setStyleSheet(Qsscontent);
    file.close();
}
//数据库的数据导入
void Widget::Sqlite()
{
    p->db=QSqlDatabase::addDatabase("QSQLITE");
    p->db.setDatabaseName("./data.db");
    if (!p->db.open()) {
        qDebug() << "Failed to open database:" << p->db.lastError().text();
    }
    QSqlQuery query;

    query.exec("CREATE TABLE IF NOT EXISTS musicdata (musictime text,musicname text,musicurl text)");
    if (query.lastError().isValid()) {
        qDebug() << "Failed to create table:" << query.lastError().text();
    }
    query.exec("SELECT * FROM musicdata");
    while (query.next()) {
        QString musictime = query.value(0).toString();
        QString musicname = query.value(1).toString();
        QString musicurl = query.value(2).toString();
        qDebug() << "Musictime:" << musictime << "Musicname:" << musicname << "Musicurl:" << musicurl;
        p->Musictime[p->Musictime.size()]=query.value(0).toString();
        p->Musicname[p->Musicname.size()]=query.value(1).toString();
        p->Musicurl[p->Musicurl.size()]=query.value(2).toString();
        ui->mysong->addItem(query.value(1).toString());
    }
}

//搜索按钮点击的槽函数
void Widget::on_search_for_clicked()
{
    QNetworkRequest request;
    request.setUrl(QString("http://iwxyi.com:3000/search?keywords=%0").arg(ui->seach_for_song->text()));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded; charset=UTF-8");
    request.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36");
    p->http_acc->get(request);
    ui->song->clear();
}
//网易云音乐的Json解析
void Widget::recv_ack(QNetworkReply *r)
{
    int count=0;
    p->searchmusictime.clear();
    p->searchmusicname.clear();
    p->searchmusicurl.clear();
    QByteArray data;
    int musicId;
    int music_duration;
    int fee;
    QString musicname;
    QString singername;
    data=r->readAll();
    QJsonParseError err;
    QJsonDocument json=QJsonDocument::fromJson(data,&err);
    if(err.error!=QJsonParseError::NoError)
    {
        qDebug()<<"err"<<err.errorString();
        return;
    }
    QJsonObject object=json.object();
    QStringList keys=object.keys();
    if(keys.contains("result"))
    {
        QJsonObject result=object["result"].toObject();
        QStringList rkeys=result.keys();
        if(result.contains("songs"))
        {

            QJsonArray arr=result["songs"].toArray();
            for(auto i:arr)
            {
                QJsonObject object_1=i.toObject();
                if(object_1["fee"].toInt()==1)                //过滤vip歌曲
                    continue;
                musicId=object_1["id"].toInt();
                music_duration=object_1["duration"].toInt();
                musicname=object_1["name"].toString();

                QStringList artistsKeys = object.keys();
                if(artistsKeys.contains("artists"))
                {
                    QJsonArray artistsArray = object["artists"].toArray();
                    for(auto j : artistsArray)
                    {
                        QJsonObject object_2 = j.toObject();
                        singername = object_2["name"].toString();         // 歌手名
                    }
                }
                p->searchmusictime[count]=QString::number(music_duration);//音乐总时长
                p->searchmusicname[count]=musicname;//音乐名字
                p->searchmusicurl[count]="https://music.163.com/song/media/outer/url?id="+QString::number(musicId);//音乐URL
                count++;
            }
        }
    }
    for(int i=0;i<p->searchmusicname.size();i++)
    {
        ui->song->addItem(p->searchmusicname[i]);
    }
}
//搜索后在线播放
void Widget::onlinePlay()
{
    p->isplay=true;
    p->player->setMedia(QUrl(p->searchmusicurl[p->songrow]));
    qDebug()<<p->searchmusicurl[p->songrow]<<endl;
    p->url=p->searchmusicurl[p->songrow];
    p->player->play();
    ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
    ui->playing->setText(p->searchmusicname[p->songrow]);
}
//创建加入歌单选项
void Widget::showContextMenu(const QPoint& pos)
{
    QPoint globalPos = ui->song->mapToGlobal(pos);
    QMenu contextMenu(this);
    QAction action("加入歌单", this);
    connect(&action, &QAction::triggered, this, &Widget::addToPlaylist);
    contextMenu.addAction(&action);
    contextMenu.exec(globalPos);
}

//循环播放和单曲循环
void Widget::LoopPlayback()
{
    if(p->songswitch)
    {
        on_nextsong_clicked();
    }
    else
    {
        p->player->setMedia(QUrl(p->url));
        p->player->play();
        ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
    }
}

//右击加入我的歌单
void Widget::addToPlaylist()
{

    bool flag=false;
    for(int i=0;i<p->Musicurl.size();i++)
    {
        if(p->searchmusicurl[ui->song->currentRow()]==p->Musicurl[i])
        {
            flag=true;
            break;
        }
    }
    if(flag==false)
    {
        ui->mysong->addItem(p->searchmusicname[ui->song->currentRow()]);
        p->Musictime[p->Musictime.size()]=p->searchmusictime[ui->song->currentRow()];
        p->Musicname[p->Musicname.size()]=p->searchmusicname[ui->song->currentRow()];
        p->Musicurl[p->Musicurl.size()]=p->searchmusicurl[ui->song->currentRow()];
    }
}

void Widget::showMysongMenu(const QPoint &pos)
{
    QPoint globalPos = ui->mysong->mapToGlobal(pos);
    QMenu contextMenu(this);
    QAction action("删除", this);
    connect(&action, &QAction::triggered, this, &Widget::removeToMysong);
    contextMenu.addAction(&action);
    contextMenu.exec(globalPos);
}
//从我的歌单移除歌曲
void Widget::removeToMysong()
{
    if(p->Musicname.size()==1)
    {
        if(p->Musicurl[0]==p->url)
        {
            p->isplay=false;
            p->player->pause();
            ui->cease_start->setIcon(QIcon(":/picture/start.png"));
            p->Musicurl.clear();
            p->Musicname.clear();
            p->Musictime.clear();
            QListWidgetItem *item = ui->mysong->takeItem(ui->mysong->currentRow());
            delete item;

        }
        else
        {
            p->Musicurl.clear();
            p->Musicname.clear();
            p->Musictime.clear();
            QListWidgetItem *item = ui->mysong->takeItem(ui->mysong->currentRow());
            delete item;
        }
    }
    else
    {
        if(p->Musicurl[ui->mysong->currentRow()]==p->url)
        {
            on_nextsong_clicked();
            std::queue<QString> temp1;
            std::queue<QString> temp2;
            std::queue<QString> temp3;
            for(int i=0;i<p->Musicurl.size();i++)
            {
                if(i!=ui->mysong->currentRow())
                {
                    temp1.push(p->Musicurl[i]);
                    temp2.push(p->Musicname[i]);
                    temp3.push(p->Musictime[i]);
                }
            }
            p->Musicurl.clear();
            p->Musicname.clear();
            p->Musictime.clear();
            int count=0;
            while (!temp1.empty()) {
                p->Musicurl[count]=temp1.front();
                temp1.pop();
                p->Musicname[count]=temp2.front();
                temp2.pop();
                p->Musictime[count]=temp3.front();
                temp3.pop();
                count++;
            }
            QListWidgetItem *item = ui->mysong->takeItem(ui->mysong->currentRow());
            delete item;
        }
        else
        {
            std::queue<QString> temp1;
            std::queue<QString> temp2;
            std::queue<QString> temp3;
            for(int i=0;i<p->Musicurl.size();i++)
            {
                if(i!=ui->mysong->currentRow())
                {

                    temp1.push(p->Musicurl[i]);
                    temp2.push(p->Musicname[i]);
                    temp3.push(p->Musictime[i]);
                }
            }
            p->Musicurl.clear();
            p->Musicname.clear();
            p->Musictime.clear();
            int count=0;
            while (!temp1.empty()) {
                p->Musicurl[count]=temp1.front();
                temp1.pop();
                p->Musicname[count]=temp2.front();
                temp2.pop();
                p->Musictime[count]=temp3.front();
                temp3.pop();
                count++;
            }
            QListWidgetItem *item = ui->mysong->takeItem(ui->mysong->currentRow());
            delete item;
        }
    }
}
//声音的控制
void Widget::soundmove()
{
    p->player->setVolume(ui->sound->value());
}
//音乐的暂停和播放
void Widget::on_cease_start_clicked()
{
    if(p->isplay)
    {
        if(p->player->state()==QMediaPlayer::PlayingState)
        {
            ui->cease_start->setIcon(QIcon(":/picture/start.png"));
            p->player->pause();
            p->timer.stop();

        }
        else
        {
            ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
            p->player->play();
            ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
            p->timer.start(500);
        }
    }
}
//本地歌曲
void Widget::on_localsong_clicked()
{
    p->isplay=true;
    QString file = QFileDialog::getOpenFileName(this,"Open File","../music","mp3 Files (*.mp3)");
    if(file.isEmpty()==false)
    {
        p->player->setMedia(QUrl(file));
        p->url=file;
        QListWidgetItem *item = new QListWidgetItem(file.split("/").last());
        ui->playing->setText(item->text());
        connect(p->player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status){
            if(status == QMediaPlayer::LoadedMedia)
            {
                // 在这里进行播放操作
                p->player->play();
                ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
                bool flag=false;
                for(int i=0;i<p->Musicurl.size();i++)
                {
                    if(p->Musicurl[i]==file)
                    {
                        flag=true;
                    }
                }
                if(flag==false)
                {
                    ui->mysong->addItem(item);
                    p->Musictime[p->Musictime.size()]=QString::number(p->player->duration());
                    p->Musicname[p->Musicname.size()]=item->text();
                    p->Musicurl[p->Musicurl.size()]=p->url;
                    p->mysongrow=ui->mysong->count()-1;
                }
            }
        });
    }
}
//下一首歌曲
void Widget::on_nextsong_clicked()
{

    if(p->Musicname.size()!=0)
    {
        qDebug()<<p->mysongrow<<endl;
        p->mysongrow=(p->mysongrow+p->Musicname.size()+1)%p->Musicname.size();
        qDebug()<<p->mysongrow<<endl;
        p->player->setMedia(QUrl(p->Musicurl[p->mysongrow]));
        ui->playing->setText(ui->mysong->item(p->mysongrow)->text());
        p->url=p->Musicurl[p->mysongrow];
        p->player->play();
        ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
        ui->playing->setText(p->Musicname[p->mysongrow]);
    }

}
//上一首歌曲
void Widget::on_previoussong_clicked()
{
    if(p->Musicname.size()!=0)
    {
        qDebug()<<p->mysongrow<<endl;
        p->mysongrow=(p->mysongrow+p->Musicname.size()-1)%p->Musicname.size();
        qDebug()<<p->mysongrow<<endl;
        p->player->setMedia(QUrl(p->Musicurl[p->mysongrow]));
        ui->playing->setText(ui->mysong->item(p->mysongrow)->text());
        p->url=p->Musicurl[p->mysongrow];
        p->player->play();
        ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
        ui->playing->setText(p->Musicname[p->mysongrow]);

    }
}
//循环播放和单曲循环的切换
void Widget::on_songswitch_clicked()
{
    if(p->songswitch)
    {
        ui->songswitch->setIcon(QIcon(":/picture/sibgle_cycle.png"));
        p->songswitch=false;
    }
    else
    {
        ui->songswitch->setIcon(QIcon(":/picture/cyclic.png"));
        p->songswitch=true;
    }
}
//播放和暂停
void Widget::onMediaStatusChanged(QMediaPlayer::MediaStatus status)
{
    if (status == QMediaPlayer::EndOfMedia)
    {
        if(p->songswitch)
        {
            if(p->Musicname.size()==0)
            {
                p->player->setMedia(QUrl(p->url));
                p->player->play();
                ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
            }
            else
            {
                on_nextsong_clicked();
            }
        }
        else
        {
            p->player->setMedia(QUrl(p->url));
            p->player->play();
            ui->cease_start->setIcon(QIcon(":/picture/pause.png"));
        }
    }
}
//点击音量按钮，音量滑轨的显示和隐藏
void Widget::on_volume_clicked(bool checked)
{
    if(checked)
    {
        ui->sound->setVisible(true);
    }
    else
    {
        ui->sound->setVisible(false);
    }
}

void Widget::on_personalization_clicked()
{
    p->count=(p->count+1)%4;
    qDebug()<<p->count<<endl;
    if(p->count==0)
    {
        Initqss(":/qss/0.qss");
    }
    if(p->count==1)
    {
        Initqss(":/qss/1.qss");
    }
    if(p->count==2)
    {
        Initqss(":/qss/2.qss");
    }
    if(p->count==3)
    {
        Initqss(":/qss/3.qss");
    }

}
